/**
 * Esta classe ira conter as acoes de um caixa.
 */

package controlador;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;

import modelo.Funcionario;
import modelo.Produto;

public class SistemaCaixa {
	private DBController db;
	private static SistemaCaixa instanciaUnica = null;
	private HashMap<Integer, Produto> carrinho = new HashMap<Integer, Produto>();
	private HashMap<Integer, Double> carrinhoUnidades = new HashMap<Integer, Double>();
	HashSet<Integer> itensCancelados = new HashSet<Integer>();
	private double precoTotal;
	private int numItens;
	private BufferedWriter notaFiscalNova;
	
	/**
	 * Verifica se nao ha nenhuma instancia em execucao desse controlador
	 * e cria um novo caso nao exista.
	 */
	public static SistemaCaixa getInstance(Funcionario func) throws SQLException {
		if (instanciaUnica == null){
			instanciaUnica = new SistemaCaixa(func);			
		}
		return instanciaUnica;
	}

	private SistemaCaixa(Funcionario func) throws SQLException {
		db = DBController.getInstance();
	}
	
	/**
	 * Coloca o produto especificado no carrinho de compras e
	 * aumenta o valor total da compra.
	 * @throws DadosIncorretosException unidades igual ou menor que zero
	 */
	public void colocarNoCarrinho(Produto p, double unidades) {
		// Adiciona ao HashMap o produto e as unidades
		carrinho.put(getNumItens(), p);
		carrinhoUnidades.put(getNumItens(), unidades);
		// Aumenta o preco total da compra
		setPrecoTotal(getPrecoTotal() + p.getPreco() * unidades);
		// Aumenta o numero de itens da compra
		setNumItens(getNumItens() + 1);
	}
	
	/**
	 * Remove o produto especificado do carrinho de compras e
	 * subtrai seu valor do total.
	 * @throws DadosIncorretosException Nao pode remover produto
	 */
	public void removerDoCarrinho(int numItem) throws DadosIncorretosException {
		// Vejo se o produto ja nao foi cancelado
		if (!itensCancelados.contains(numItem)) {

			// Pega o produto que quer remover
			Produto p = carrinho.get(numItem);
			// Pega as unidades daquele produto e inverto seu valor
			double unidades = (-1) * carrinhoUnidades.get(numItem);

			// Coloco o numero daquele item na lista de cancelados pra nao ser cancelado de novo
			itensCancelados.add(numItem);

			// Adiciono no carrinho esse produto com valor negativo
			colocarNoCarrinho(p, unidades);

		}
	}
	
	public Produto getProdutoCarrinho(int numItem) {
		Produto p = carrinho.get(numItem);
		double unidades = carrinhoUnidades.get(numItem);
		p.setUnidades(unidades);
		
		return p;
	}
	
	public boolean produtoJaFoiRemovido (int numItem) {
		if (itensCancelados.contains(numItem)) {
			return true;
		}
		
		return false;
	}

	/**
	 * Limpa as informacoes da compra atual para comecar uma nova.
	 */
	public void iniciarNovaCompra() {
		// Esvazia o carrinho de compras
		carrinho.clear();
		// Esvazio a lista de cancelados
		itensCancelados.clear();
		// Zera o valor total da compra
		setPrecoTotal(0.0);
		// Zera o numero de itens da compra
		setNumItens(0);
	}
	
	/**
	 * Retira os itens vendidos do estoque e comeca uma nova compra.
	 */
	public void finalizarCompra() throws EntradaNaoEncontradaException {
		// Remover produto por produto do estoque
		for (int i = 0; i < getNumItens(); i++) {
			Produto p = carrinho.get(i);
			double unidades = carrinhoUnidades.get(i);
			
			tiraDoEstoque(p.getCodigo(), unidades);
			//System.out.println("Removeu " + p.getNome() + " em " + unidades + " unidades do estoque.");
		}
		
		iniciarNovaCompra();
		
	}
	
	public Produto getProduto(int codigo) throws EntradaNaoEncontradaException {
		return db.getProduto(codigo);
	}

	public double getPrecoTotal() {
		return precoTotal;
	}
/*
	private void addPrecoTotal(double precoTotal) {
		this.precoTotal += precoTotal;
	}*/
	
	private void setPrecoTotal(double precoTotal) {
		this.precoTotal = precoTotal;
	}

	public int getNumItens() {
		return numItens;
	}

	private void setNumItens(int numItens) {
		this.numItens = numItens;
	}
	
	private void tiraDoEstoque(int codigo, double unidades) throws EntradaNaoEncontradaException{
		Produto p = getProduto(codigo);

		p.setVendidos(p.getVendidos() + unidades);
		p.setUnidades(p.getUnidades() - unidades);

		db.atualizaProduto(p);
	}
	
	public BufferedWriter geraNovaNotaFiscal(){
		try {
			notaFiscalNova = new BufferedWriter(new FileWriter("NotaFiscal.txt"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return notaFiscalNova;
		
	}

}